<?php
class DbDriverMysqli
{
	protected $link;
	//protected $persist=false;
	
	static function instance($host, $user, $passwd, $db/*, $persist=false*/)
	{
		$mysqli = new mysqli($host, $user, $passwd, $db);
		if(mysqli_connect_errno())
		{
			Show::error("Open connection failure [".mysqli_error()."]");
		}
		$mysqli->query('SET NAMES `utf8`');
		$mysqli->autocommit(true);
		
		$obj	=	new DbDriverMysqli();
		$obj->link	=	$mysqli;
		$obj->trans	= new MySqliTransaction($mysqli);
		//$obj->persist	=	$persist;
		return $obj;
	}
	
	static function qu()
	{
		return '`';
	}
	
	function close()
	{
		return $this->link->close();
		//return $this->persist ? true : $this->link->close();
	}
	
	function insertId()
	{
		return $this->link->insert_id;
	}
	
	function query($sql)
	{
		return $this->link->query($sql);
	}
	
	function fetchAll($result)
	{
		if(!$result || !is_a($result, 'mysqli_result'))
			return null;
		$rows	=	array();
		while($r=$result->fetch_assoc())
		{
			$rows[]	=	$r;
		}
		$result->free();
		return $rows;
	}
	function fetchOne($result)
	{
		if(!$result || !is_a($result, 'mysqli_result'))
			return null;
		$row	=	$result->fetch_assoc();
		$result->free();
		return $row;
	}
	
	function fields($table)
	{
		$res	=	$this->link->query("SHOW FIELDS FROM `{$table}`");
		if($res) {
			$rows	=	array();
			$pk		=	'';
			while($r=$res->fetch_assoc())
			{
				if(false!==strpos($r['Type'], 'int'))
				{
					$rows[$r['Field']]	=	1;
				}
				elseif(false!==strpos($r['Type'], 'float') 
					|| false!==strpos($r['Type'], 'double') 
					|| false!==strpos($r['Type'], 'decimal'))
				{
					$rows[$r['Field']]	=	2;
				}
				else
				{
					$rows[$r['Field']]	=	0;
				}
				
				if(!$pk && $r['Key']=='PRI')
				{
					$pk	=	$r['Field'];
				}
			}
			if($pk)
			{
				$rows['_pk']	=	$pk;
			}
			$res->free();
			return $rows;
		}

		if(MOD_DEBUG){
			trigger_error(sprintf("Fail to get table fields: <i>%s</i>", $this->lastError()));
		}

		return false;
	}
	
	function qstr($s)
	{
		return $this->link->real_escape_string($s);
	}
	
	function lastError()
	{
		return sprintf('[%d]%s', $this->link->errno, $this->link->error);
	}
	
	function makeLimit($s, $l)
	{
		return "LIMIT $s,$l";
	}
	
	function affectedRows()
	{
		return $this->link->affected_rows;
	}
	
}

/**
  事务的实现
  */
class MySqliTransaction{

	private $link = null;
	private $num = 0;

	public function __construct($link){
		$this->link = $link;
	}

	public function on(){
		if($this->num++ ==0){
			$this->link->autocommit(false);
		}
	}

	public function off(){
		if(--$this->num ==0){
			$this->link->autocommit(true);
		}
		elseif($this->num<0){
			Show::fault('Unmatched trans on/off.');
		}
	}

	public function commit($auto_off=true){
		$this->link->commit();
		if($auto_off){
			$this->off();
		}
	}

	public function rollback($auto_off=true){
		$this->link->rollback();
		if($auto_off){
			$this->off();
		}
	}

}

?>
